package ai.people.core.nebula.config;

import ai.people.core.nebula.factory.NebulaSessionFactoryBean;
import ai.people.core.nebula.properties.ConnectProperties;
import com.vesoft.nebula.client.graph.NebulaPoolConfig;
import com.vesoft.nebula.client.graph.SessionsManagerConfig;
import com.vesoft.nebula.client.graph.net.NebulaPool;
import com.vesoft.nebula.client.graph.net.SessionsManager;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.util.Assert;

import java.net.UnknownHostException;

/**
 * nebula配置类
 *
 * @author zhenglin
 * @since 2022/3/28
 */
@Configuration
@RequiredArgsConstructor
@Import(NebulaSessionFactoryBean.class)
@EnableConfigurationProperties(ConnectProperties.class)
@ComponentScan(basePackages = "ai.people.core.nebula")
public class NebulaAutoConfiguration {

    public static final Logger LOGGER = LoggerFactory.getLogger(NebulaAutoConfiguration.class);

    /**
     * 连接属性
     */
    private final ConnectProperties connectProperties;

    /**
     * nebulaPool池
     *
     * @return {@link NebulaPool}
     * @throws UnknownHostException 未知主机异常
     */
    @Bean
    @ConditionalOnProperty(value = "nebula.enabled", havingValue = "true")
    public NebulaPool nebulaPool() throws UnknownHostException {
        NebulaPool pool = new NebulaPool();
        Assert.notNull(connectProperties, "The value must not be null");
        NebulaPoolConfig poolConfig = new NebulaPoolConfig();
        poolConfig.setMaxConnSize(connectProperties.getMaxConnsSize());
        poolConfig.setMinConnSize(connectProperties.getMinConnsSize());
        poolConfig.setIdleTime(connectProperties.getIdleTime());
        poolConfig.setTimeout(connectProperties.getTimeout());
        poolConfig.setIntervalIdle(connectProperties.getIntervalIdle());
        poolConfig.setWaitTime(connectProperties.getWaitTime());
        poolConfig.setEnableSsl(connectProperties.isEnableSsl());
        poolConfig.setSslParam(connectProperties.getSslParam());
        boolean initResult = pool.init(connectProperties.builderUrl(), poolConfig);
        Assert.isTrue(initResult, "nebula初始化失败");
        LOGGER.info("init nebula pool form url:{}", connectProperties.getUrl());
        return pool;
    }

    @Bean
    @ConditionalOnProperty(value = "nebula.enabled", havingValue = "true")
    public SessionsManager sessionsManager(){
        SessionsManagerConfig config = new SessionsManagerConfig();
        NebulaPoolConfig poolConfig = new NebulaPoolConfig();
        poolConfig.setMaxConnSize(connectProperties.getMaxConnsSize());
        poolConfig.setMinConnSize(connectProperties.getMinConnsSize());
        poolConfig.setEnableSsl(connectProperties.isEnableSsl());
        poolConfig.setIdleTime(connectProperties.getIdleTime());
        poolConfig.setSslParam(connectProperties.getSslParam());
        poolConfig.setTimeout(connectProperties.getTimeout());
        poolConfig.setWaitTime(connectProperties.getWaitTime());
        config.setPoolConfig(poolConfig);
        config.setAddresses(connectProperties.builderUrl());
        config.setUserName(connectProperties.getUsername());
        config.setPassword(connectProperties.getPassword());
        config.setSpaceName(connectProperties.getSpaceName());
        return new SessionsManager(config);
    }

}
